<template>
  <Form
    ref="labForm"
    :model="labForm"
    :rules="ruleValidate"
    :label-position="label.position"
    :label-width="label.width"
  >
    <fieldset class="line-field">
      <legend>实验室基本信息</legend>
      <FormItem label="所属学院" prop="institute">
        <Select
          v-model="labForm.institute"
          filterable
          :disabled="!user.access.some(item => { return ['ROLE_ROOT', 'ROLE_SCHOOL_ADMIN'].indexOf(item) > -1 }) && !reChooseInstitute"
          :enabledPreventOverflow="enabledPreventOverflow"
          :not-found-text="loading.institute ? '查询学院中，请稍等...' : '无可选学院'"
          @on-change="onChangeInstitute"
          placeholder="请选择学院"
        >
          <Option
            v-for="(option, index) in options.institute"
            :value="option"
            :key="index"
          >{{option}}</Option>
        </Select>
      </FormItem>
      <FormItem label="负责人" prop="teacherCode">
        <Select
          v-model="labForm.teacherCode"
          filterable
          :enabledPreventOverflow="enabledPreventOverflow"
          :not-found-text="loading.teacher ? '查询教师中，请稍等...' : '无可选教师'"
          placeholder="请选择教师"
        >
          <Option
            v-for="(option, index) in options.teacher"
            :value="option.code"
            :key="index"
          >{{option.name}}</Option>
        </Select>
      </FormItem>
      <FormItem label="名称" prop="name">
        <Input v-model="labForm.name" placeholder="请输入实验室名称，如：物联网实验室" />
      </FormItem>
      <Row :gutter="16" type="flex" justify="space-between">
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="房间号" prop="code">
            <Input v-model="labForm.code" placeholder="请输入实验室房间号，如：8B403" />
          </FormItem>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="容纳人数" prop="capacity">
            <InputNumber :min="0" v-model="labForm.capacity" placeholder="请输入该实验室的容纳人数" style="width: 100%"></InputNumber>
          </FormItem>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="实验箱数" class="not-required-item">
            <InputNumber :min="0" v-model="labForm.numOfExpBox" placeholder="请输入该实验室的实验箱数量" style="width: 100%"></InputNumber>
          </FormItem>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="电脑数" prop="numOfPC">
            <InputNumber :min="0" v-model="labForm.numOfPC" placeholder="请输入该实验室的电脑数量" style="width: 100%"></InputNumber>
          </FormItem>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="方向" class="not-required-item">
            <Input v-model="labForm.field" placeholder="请输入实验室方向，如：电子商务" />
          </FormItem>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="实验室状态" prop="status">
            <RadioGroup v-model="labForm.status">
              <Radio label="ACTIVATING">可用</Radio>
              <Radio label="UNACTIVATED" style="margin-left: 20px;">不可用</Radio>
            </RadioGroup>
          </FormItem>
        </Col>
        <Col span="24">
          <Alert type="info" show-icon closable>
            温馨提示：
            <div slot="desc">
              <p>一、<strong>实验室总面积：</strong><span>实验室使用面积仅为学生实验场所的使用面积，不包括实验准备室等。</span></p>
              <p>二、<strong>每生占有标准面积：</strong><span>基础、专业实验室为3.5平方米/生，机房、语音室为1.5平方米/生。</span></p>
              <p>三、<strong>额定课时数：</strong>
                <span>基础课和专业（技术）基础课实验室，教育部规定
                  <strong>每学年64800人时数</strong>，
                  <strong>每学年</strong>实验室额定课时数为<strong>900</strong>课时（36周 &times; 5天/周 &times; 5课时/天）；
                  计算机房、语言（音）实验室的额定课时数为<strong>1080</strong>课时（36周 &times; 5天/周 &times; 6课时/天）。
                </span>
              </p>
            </div>
          </Alert>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="实验室总面积" prop="area">
            <InputNumber :min="1" :step="50" v-model="labForm.area" placeholder="请输入该实验室的总面积(平方米)" style="width: 100%"></InputNumber>
          </FormItem>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="每生占有标准面积" prop="perStudentArea">
            <InputNumber :min="1" :step="50" v-model="labForm.perStudentArea" placeholder="请输入每生占有标准面积(平方米/生)" style="width: 100%"></InputNumber>
          </FormItem>
        </Col>
        <Col :xs="24" :sm="24" :md="12">
          <FormItem label="额定课时数(每学期)" prop="ratedClassHours">
            <InputNumber :min="1" :step="50" v-model="labForm.ratedClassHours" placeholder="请输入该实验室的额定课时数" style="width: 100%"></InputNumber>
          </FormItem>
        </Col>
      </Row>
      <div class="text-center">
        <Poptip
            confirm
            title="确定提交表单吗？"
            word-wrap
            width="180"
            @on-ok="handleSubmit('labForm')"
            class="text-left"
            :options="popperOpts">
            <Button type="success" class="mr-20">
              <span>提交表单</span>
            </Button>
        </Poptip>
        <Poptip
            confirm
            title="数据将不可恢复，确定重置表单吗？"
            word-wrap
            width="180"
            @on-ok="handleReset('labForm')"
            class="text-left"
            :options="popperOpts">
          <Button style="margin-left: 8px">重置表单</Button>
        </Poptip>
      </div>
    </fieldset>
  </Form>
</template>
<script>
import { mapActions } from 'vuex'
import { getInstituteList, getTeacherList, submitSaveLab, getLabById } from '@/api/lab-mgmt'
export default {
  name: 'LabSave',
  data () {
    return {
      options: {
        institute: [],
        teacher: []
      },
      loading: {
        institute: true,
        teacher: false,
        submit: false
      },
      // 当前登录用户相关信息
      user: {
        code: '',
        name: '',
        access: [],
        institute: ''
      },
      labForm: {
        id: null,
        institute: '',
        // 实验室负责教师的工号
        teacherCode: null,
        // 实验室名称
        name: null,
        // 实验室房间号
        code: null,
        // 实验室方向
        field: null,
        // 电脑数量
        numOfPC: null,
        // 实验箱数量
        numOfExpBox: null,
        // 可容纳人数
        capacity: null,
        // 实验室激活状态: ACTIVATING 激活 , UNACTIVATED 未激活
        status: 'ACTIVATING',
        // 额定课时数
        ratedClassHours: null,
        // 实验室使用面积
        area: null,
        // 每生占有标准面积
        perStudentArea: null
      },
      ruleValidate: {
        institute: [
          {required: true, message: '学院不能为空', trigger: 'change'}
        ],
        teacherCode: [
          {required: true, message: '负责人不能为空', trigger: 'change'}
        ],
        name: [
          {required: true, message: '实验室名称不能为空', trigger: 'blur'}
        ],
        field: [
          {required: true, message: '实验室方向不能为空', trigger: 'blur'}
        ],
        code: [
          {required: true, message: '房间号不能为空', trigger: 'blur'}
        ],
        numOfPC: [
          {required: true, type: 'number', message: '电脑数量不能为空', trigger: 'change'},
          {required: true, type: 'number', message: '电脑数量不能为空', trigger: 'blur'}
        ],
        numOfExpBox: [
          {required: true, type: 'number', message: '实验箱数量不能为空', trigger: 'change'},
          {required: true, type: 'number', message: '实验箱数量不能为空', trigger: 'blur'}
        ],
        capacity: [
          {required: true, type: 'number', message: '容纳人数不能为空', trigger: 'change'},
          {required: true, type: 'number', message: '容纳人数不能为空', trigger: 'blur'}
        ],
        status: [
          {required: true, message: '请选择实验室状态', trigger: 'change'}
        ],
        ratedClassHours: [
          {required: true, type: 'number', message: '额定课时数不能为空', trigger: 'change'},
          {required: true, type: 'number', message: '额定课时数不能为空', trigger: 'blur'}
        ],
        area: [
          {required: true, type: 'number', message: '实验室面积不能为空', trigger: 'change'},
          {required: true, type: 'number', message: '实验室面积不能为空', trigger: 'blur'}
        ],
        perStudentArea: [
          {required: true, type: 'number', message: '每生占有标准面积不能为空', trigger: 'change'},
          {required: true, type: 'number', message: '每生占有标准面积不能为空', trigger: 'blur'}
        ]
      },
      label: {
        position: 'left',
        width: 130
      },
      // 是否可以重新选择学院，学院拆了之后，可能有旧学院存在实验室信息中，需要重新选择学院
      reChooseInstitute: false,
      // Select选择器的下拉列表是否吸附，默认为true，吸附
      enabledPreventOverflow: false,
      popperOpts: {
        modifiers: {
          preventOverflow: {
            // 边界元素: scrollParent, window, viewport or any DOM element. 默认iview默认window
            boundariesElement: 'scrollParent'
          }
        }
      }
    }
  },
  props: {
    // 当前是否为修改状态
    isModified: {
      type: Boolean,
      default: false
    },
    // 原申请表id
    labId: {
      type: Number,
      default: null
    },
    // 原申请表的负责人姓名
    oriTeacherName: {
      type: String,
      default: null
    }
  },
  methods: {
    ...mapActions(['getUserInfo']),
    // 获取学院列表
    async getInstituteOptions () {
      this.loading.institute = true
      let options = []
      try {
        let res = await getInstituteList()
        res = res.data
        if (res.code && res.data.length > 0) {
          options = res.data
        } else {
          this.$Notice.error({
            title: res.code ? '暂无学院' : '获取学院列表失败',
            desc: res.code ? '暂无可选学院，请刷新后重试' : res.info
          })
          options = []
        }
      } catch (error) {
        console.log(error)
        this.$Notice.error({
          title: '获取学院列表失败',
          desc: error
        })
        options = []
      }
      this.loading.institute = false
      return options
    },
    // 获取教师列表
    async getTeacherOptions (institute) {
      this.loading.teacher = true
      let options = []
      try {
        let res = await getTeacherList(institute)
        res = res.data
        if (res.code) {
          if (res.data.length > 0) {
            options = res.data
          } else {
            this.$Notice.error({
              title: '无匹配数据',
              desc: '该学院暂无可选教师，请选择其他学院'
            })
            options = []
          }
        } else {
          this.$Notice.error({
            title: '获取教师列表失败',
            desc: res.info
          })
          options = []
        }
      } catch (error) {
        console.log(error)
        this.$Notice.error({
          title: '获取教师列表失败',
          desc: error
        })
        options = []
      }
      this.loading.teacher = false
      return options
    },
    // created生命周期内的获取学院和教师列表
    async createdHandleOptions () {
      if (
        this.user.access.some(item => {
          return ['ROLE_ROOT', 'ROLE_SCHOOL_ADMIN'].indexOf(item) > -1
        })
      ) {
        // 校级管理员可以获取所有学院
        this.options.institute = await this.getInstituteOptions()
        if (this.options.institute.length <= 0) {
          return false
        }
      } else {
        // 非校级管理员
        this.options.institute = [this.user.institute]
      }
      this.options.teacher = await this.getTeacherOptions(this.user.institute)
      if (!this.isModified) {
        this.labForm.institute = this.user.institute
        this.labForm.teacherCode = this.user.code
      }
    },
    // 改变学院select的回调函数
    async onChangeInstitute (value) {
      this.labForm.teacherCode = null
      if (value) {
        this.options.teacher = await this.getTeacherOptions(value)
      }
    },
    // 清除表单数据
    resetFormData () {
      this.labForm = {
        id: this.labForm.id,
        institute: this.user.institute,
        // 实验室负责教师的工号
        teacherCode: this.user.code,
        // 实验室名称
        name: null,
        // 实验室房间号
        code: null,
        // 实验室方向
        field: null,
        // 电脑数量
        numOfPC: null,
        // 实验箱数量
        numOfExpBox: null,
        // 可容纳人数
        capacity: null,
        // 实验室激活状态: ACTIVATING 激活 , UNACTIVATED 未激活
        status: 'ACTIVATING'
      }
    },
    // 提交表单
    async handleSubmit (name) {
      this.loading.submit = true
      this.$refs[name].validate(async (valid) => {
        if (valid) {
          this.showSpinWithTip('提交表单中，请稍等...')
          try {
            let response = await submitSaveLab(JSON.stringify(this.labForm))
            let res = response.data
            if (res.code) {
              this.$emit('saveSuccess', this.isModified)
            } else {
              this.$Notice.error({
                title: '提交失败',
                desc: (this.isModified ? '修改实验室信息失败，' : '新增实验室失败，') + res.info
              })
            }
          } catch (error) {
            console.log(error)
            this.$Notice.error({
              title: '提交失败',
              desc: (this.isModified ? '修改实验室信息失败，' : '新增实验室失败，') + error
            })
          }
          this.$Spin.hide()
        } else {
          this.$Notice.error({
            title: '提交失败',
            desc: '抱歉，无法提交，请先完善表单信息再提交。'
          })
        }
      })
    },
    // 重置表单（清除验证和数据）
    handleReset (name) {
      this.$refs[name].resetFields()
      this.resetFormData()
    },
    // 修改实验室时，填充旧数据
    async fillFormByData (id) {
      let detail = await this.getLabDetailById(id)
      this.options.institute = await this.getInstituteOptions()
      if (!detail.data) {
        this.$emit('failFillFrom', detail.info)
        this.$nextTick(() => {
          this.$Spin.hide()
        })
        return false
      }
      if (this.options.institute.indexOf(detail.data.institute) < 0) {
        // 如果原申请表的学院为旧学院，则需重新选择学院
        this.$Notice.error({
          title: '提示',
          desc: '原学院（' + detail.data.institute + '）已不存在，请重新选择学院。'
        })
        this.reChooseInstitute = true
        detail.data.institute = null
        // 负责人列表暂时只赋值原申请表的负责人
        this.options.teacher = [{
          code: detail.data.teacherCode,
          name: this.oriTeacherName
        }]
      } else {
        this.options.teacher = await this.getTeacherOptions(detail.data.institute)
      }
      this.labForm = detail.data
      this.$nextTick(() => {
        this.$Spin.hide()
      })
    },
    // 通过实验室id获取实验室信息
    async getLabDetailById (id) {
      let detail = {
        data: null,
        info: ''
      }
      try {
        let res = await getLabById(id)
        res = res.data
        if (res.code) {
          detail = {
            data: res.data,
            info: ''
          }
        } else {
          // this.$Notice.error({
          //   title: '获取实验室信息失败',
          //   desc: res.info
          // })
          detail.info = res.info
        }
      } catch (error) {
        // this.$Notice.error({
        //   title: '获取实验室信息失败',
        //   desc: error
        // })
        detail.info = error
      }
      return detail
    },
    // 显示带文字提示的Spin
    showSpinWithTip (tip) {
      this.$Spin.show({
        render: h => {
          return h('div', { class: 'ivu-spin-large' }, [
            h('span', {
              class: 'ivu-spin-dot',
              style: {
                display: 'inline-block'
              }
            }),
            h('div', tip)
          ])
        }
      })
    }
  },
  watch: {
    isModified: {
      handler: function (value) {
        if (value) {
          this.fillFormByData(this.labId)
        }
      },
      immediate: true
    }
  },
  created: function () {
    if (this.isModified) {
      this.showSpinWithTip('加载表单数据中，请稍等...')
    }
    this.getUserInfo().then(response => {
      let res = response.data
      if (res.code) {
        this.user.code = this.$store.state.user.userCode // 教师工号
        this.user.name = this.$store.state.user.userName // 教师姓名
        this.user.access = this.$store.state.user.access // 教师权限
        this.user.institute = this.$store.state.user.department || '' // 教师权限
      }
      if (!this.isModified) {
        this.createdHandleOptions()
      }
    }).catch(err => {
      this.$nextTick(() => {
        this.$Spin.hide()
      })
      this.$Notice.error({
        title: '提示',
        desc: '获取用户信息失败！请重试！' + err
      })
      console.log(err)
    })
  },
  mounted: function () {
    // 全局配置Notice组件的属性
    this.$Notice.config({
      top: window.innerHeight / 3
    })
  },
  beforeDestroy () {
    this.$Notice.destroy()
  }
}
</script>

<style lang="less">
  .not-required-item {
    .ivu-form-item-label{
      padding-left: 10px;
    }
  }
</style>
